<template>
    <div class="article-container">
        <!-- 导航栏 -->
        <van-nav-bar title="黑马头条" fixed left-arrow @click-left="$router.back()" />

        <div class="main-wrap">
            <!-- 加载中 -->
            <van-loading vertical v-if="loading">加载中...</van-loading>

            <!-- 加载完成-文章详情 -->
            <div class="article-detail" v-else-if="article.title">
                <!-- 标题 -->
                <h3>{{ article.title }}</h3>

                <!-- 作者头像，名字 关注按钮等 -->
                <van-cell :title="article.aut_name">
                    <!-- 头像 -->
                    <template #icon>
                        <van-image round fit="cover" class="tou-xiang" :src="article.aut_photo" />
                    </template>
                    <!-- 发布时间 -->
                    <template #label>
                        <span>{{ article.pubdate | relativeTime }}</span>
                    </template>
                    <!-- 关注按钮 -->
                    <template #default>
                        <!-- 封装关注组件，以后可能会有多个地方用到关注组件 -->
                        <FollowUser :isFollowed.sync="article.is_followed" :authorId="article.aut_id"></FollowUser>
                    </template>
                </van-cell>

                <!-- 文章正文内容 -->
                <!-- 文章正文样式采用 github-markdown-css 处理 -->
                <div class="markdown-body" ref="articleContent" v-html="article.content">
                </div>
                <van-divider ref="vanDivider">正文结束</van-divider>

                <!-- 文章评论列表 -->
                <CommentList 
                    type="a"
                    :source="article.art_id" 
                    :commentList="commentList"
                    @getCommentsCount="commentsCount = $event"
                    @replyClick="onReplyClick">
                </CommentList>

                <!-- 底部(评论，三连等) -->
                <div class="article-bottom">
                    <van-button type="default" round size="small" @click="onPostComment">写评论</van-button>
                    <van-icon name="comment-o" :badge="commentsCount" @click="scrollToEnd"/>
                    <!-- 封装收藏组件 -->
                    <CollectArticle :isCollected.sync="article.is_collected" :articleId="article.art_id"></CollectArticle>
                    <!-- 封装点赞组件 -->
                    <LikeArticle :attitude.sync="article.attitude" :articleId="article.art_id"></LikeArticle>
                    <van-icon name="share-o" />
                </div>

                <!-- 写评论的弹出层 -->
                <van-popup v-model="show" position="bottom" :style="{ height: '17%' }" >
                    <CommentPost :target="article.art_id" v-if="show" @postSuccess="onPostSuccess"></CommentPost>
                </van-popup>

                <!-- 对评论回复的弹出层 -->
                <!-- van-popup是懒加载的，只在第一次渲染里面的内容，后面弹层关闭时，内容是一直都存在的，导致了点击不同的评论，回复内容确没有更新 -->
                <!-- 所以通过设置v-if="replyShow"，让CommentReply组件在弹层关闭时销毁 -->
                <van-popup v-model="replyShow" position="bottom" :style="{ height: '80%' }" >
                    <CommentReply :comment="currentComment" @close="replyShow = false" v-if="replyShow"></CommentReply>
                </van-popup>
            </div>

            <!-- 加载失败：404 -->
            <div class="error-wrar" v-else-if="failState === 404">
                <van-icon name="failure" />
                <p>该资源不存在或已删除！</p>
            </div>

            <!-- 加载失败：其他错误（网络原因，服务器异常等） -->
            <div class="error-wrar" v-else>
                <van-icon name="failure" />
                <p>内容加载失败！</p>
                <van-button type="default" round size="small" @click="loadArticle()">点击重试</van-button>
            </div>
        </div>
    </div>
</template>

<script>
import { getArticleById } from '@/api/article'
import { ImagePreview } from 'vant'
import FollowUser from '@/components/follow-user'
import CollectArticle from '@/components/collect-article'
import LikeArticle from '@/components/like-article'
import CommentList from './comment-list.vue'
import CommentPost from './comment-post.vue'
import CommentReply from './comment-reply.vue'

export default {
    name: 'ArticleIndex',
    components: {
        FollowUser,
        CollectArticle,
        LikeArticle,
        CommentList,
        CommentPost,
        CommentReply
    },
    props: {
        // 接收路由传过来的参数
        articleId: {
            type: [Number, String],
            required: true
        }
    },
    // provide()可以给后代（孙子）组件提供数据
    provide() {
        return {
            articleId: this.articleId
        }
    },
    data() {
        return {
            article: {}, //文章详情
            loading: true, //控制文章内容加载状态
            failState: 0, //失败状态：值为404是资源丢失
            commentsCount: 0, //文章评论条数
            show: false, //写评论弹出层的展示
            commentList: [], //评论列表
            replyShow: false, //对评论回复的弹出层的展示
            currentComment: {} //当前评论对象
        }
    },
    methods: {
        // 加载文章详情
        async loadArticle() {
            this.loading = true
            try {
                const { data } = await getArticleById(this.articleId)
                console.log(data)
                this.article = data.data
                // 这里使用setTimeout()来进行一个异步执行
                // 因为此时页面还没渲染出文章dom节点
                setTimeout(() => {
                    // 加载预览图片
                    this.previewImage()
                }, 0)

            } catch (err) {
                if (err.response && err.response.status === 404) {
                    // 资源丢失
                    this.failState = 404
                }
                console.log('数据获取失败', err)
            }
            // 关闭loading状态
            this.loading = false
        },

        // 预览图片
        previewImage() {
            // 获取所有img节点
            const articleContent = this.$refs['articleContent']
            const imgs = articleContent.querySelectorAll('img')
            const imgUrl = []
            imgs.forEach((img, index) => {
                // 注意：大多数文章图片404，
                // 该文章图片好使http://localhost:8080/#/article/8133
                imgUrl.push(img.src)
                // 为所有img绑定点击事件
                img.onclick = function () {
                    ImagePreview({
                        images: imgUrl, // 图片数组
                        startPosition: index, // 预览起始位置
                    })
                }
            })
        },

        // 滚动到文章结束位置
        scrollToEnd() {
            const height = this.$refs.vanDivider.offsetTop
            // console.log(height)
            window.scrollTo({
                top: height - 48,
                left: 0,
                behavior: "smooth"
            })
        },

        // 点击写评论按钮
        onPostComment() {
            if(!this.$store.state.user) {
                // 未登录，则跳转到登录页面
                this.$toast('您还没有登录！')
                this.$router.push('/login')        
            }else {
                // 已登录，则打开评论弹层
                this.show = true
            }
        },

        // 处理写评论弹层的关闭和评论列表内容的新增
        onPostSuccess(newComment) {
            // 关闭弹层
            this.show = false
            // 列表顶部增加新评论
            this.commentList.unshift(newComment)
            // 评论数加一
            this.commentsCount++
        },

        // 处理对评论的回复
        onReplyClick(comment) {
            this.replyShow = true
            this.currentComment = comment
        }
    },
    created() {
        this.loadArticle()
    }
}
</script>


<style lang="less" scoped>
// 文章正文样式采用 github-markdown-css 处理
@import "./github-markdown.css";

.article-container {
    padding-top: 92px;
    padding-bottom: 92px;

    .main-wrap {
        padding: 0 38px;

        .article-detail {
            h3 {
                font-size: 40px;
            }

            .van-cell {
                padding-left: 0;
                padding-right: 0;
                align-items: center;

                .tou-xiang {
                    width: 70px;
                    height: 70px;
                    margin-right: 10px;
                }

                .van-cell__label {
                    margin-top: 0;
                }
            }
        }

        .error-wrar {
            margin-top: 285px;
            color: #b4b4b4;
            text-align: center;

            .van-icon-failure {
                font-size: 125px;
            }

            p {
                font-size: 30px;
            }

            .van-button {
                border: 3px solid;
                width: 210px;
                color: #b4b4b4;
                font-size: 30px;
            }
        }
    }

    .article-bottom {
        background-color: white;
        border-top: 1px solid #b4b4b4;
        padding: 18px 0;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        display: flex;
        justify-content: space-around;
        align-items: center;

        .van-button {
            width: 282px;
            font-size: 28px;
            color: #b4b4b4;
        }

        .van-icon {
            font-size: 40px;
        }
    }
}</style>